package com.broada.apm.util;

import groovy.lang.GroovyShell;
import groovy.lang.Script;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;
import org.codehaus.groovy.control.CompilationFailedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.broada.apm.ApmServer;
import com.broada.apm.utils.ApmFileUtils;
import com.broada.apm.utils.ExceptionUtils;

public class SystemManager {
	private static Logger log = LoggerFactory.getLogger(SystemManager.class);
	private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static File filePath = null;
	private static String sysPropFilePath = null;
	private static long lastmodify;
	private static Script parsedScript;
	private static File sysPropFile = null;
	static {
		String srciptsFilePath = System.getProperty("scripts.path", "/WEB-INF/scripts");
		filePath = ApmFileUtils.getFile(srciptsFilePath+"/sysinfo.groovy");
		sysPropFilePath = ApmServer.USER_DIR + "/../webapps/front/WEB-INF/conf/system.properties";
		sysPropFile = ApmFileUtils.getAbsoluteFile(sysPropFilePath);
		lastmodify = filePath.lastModified();
	}

	@SuppressWarnings("rawtypes")
	public synchronized static LinkedHashMap SystemInfo() {
		try {
			parseScript();
			return (LinkedHashMap) parsedScript.run();
		} catch (IOException e) {
			ExceptionUtils.error(log, "获取系统信息失败", e);
		}
		return null;
	}

	private static void parseScript() throws CompilationFailedException, IOException {
		if(parsedScript == null || lastmodify < filePath.lastModified()) {
			GroovyShell groovyShell = new GroovyShell();
			parsedScript = groovyShell.parse(filePath);
			lastmodify = filePath.lastModified();
		}
	}

	public static void updateHostName(String name) throws Exception {
		GroovyShell groovyShell = new GroovyShell();
		Script scrpt = groovyShell.parse(filePath);
		String result = (String) scrpt.invokeMethod("updateHostName", name);
		if (StringUtils.isNotEmpty(result))
			throw new Exception(result);
		
	}

	public static void updateHostDate(Date date) throws Exception {
		GroovyShell groovyShell = new GroovyShell();
		String _date = formatter.format(date);
		Script scrpt = groovyShell.parse(filePath);
		String result = (String) scrpt.invokeMethod("updateHostDate", _date);
		if (StringUtils.isNotEmpty(result))
			throw new Exception(result);
	}

	/**
	 * 修改指定网卡的ip/netmask
	 * 
	 * @param eth
	 * @param ip
	 * @param netmast
	 * @param gateway 
	 * @throws Exception
	 * @throws IOException
	 */
	public static void updateHostIpNetMast(String eth, String ip, String netmast, String gateway) throws Exception, IOException {
		GroovyShell groovyShell = new GroovyShell();
		Script scrpt = groovyShell.parse(filePath);
		String result = (String) scrpt.invokeMethod("updateHostIpNetMast", new String[] { eth, ip, netmast, gateway });
		if (StringUtils.isNotEmpty(result))
			throw new Exception(result);
	}

	/**
	 * 修改默认的网关
	 * 
	 * @param gateway
	 * @throws Exception
	 * @throws IOException
	 */
	public static void updateHostGateWay(String gateway) throws Exception, IOException {
		GroovyShell groovyShell = new GroovyShell();
		Script scrpt = groovyShell.parse(filePath);
		String result = (String) scrpt.invokeMethod("updateHostGateWay", gateway);
		if (StringUtils.isNotEmpty(result)&&result.indexOf("No such process")>=0)
			throw new Exception("无效的网关");
	}

	/**
	 * 修改dns 多个dns以","分隔
	 * 
	 * @param eth
	 * @param dns 
	 * @throws Exception
	 * @throws IOException
	 */
	public static void updateHostDns(String eth, String dns) throws Exception, IOException {
		GroovyShell groovyShell = new GroovyShell();
		Script scrpt = groovyShell.parse(filePath);
		String result = (String) scrpt.invokeMethod("updateHostDns", new String[] { eth, dns });
		if (StringUtils.isNotEmpty(result))
			throw new Exception(result);
	}
	
	/**
	 * 修改服务器同步时间
	 * 
	 * @param status
	 *          0：禁用 1：启用
	 * @param server
	 * @throws Exception
	 * @throws IOException
	 */
	public static void updateSyncServerDate(String status, String server) throws Exception, IOException {
		GroovyShell groovyShell = new GroovyShell();
		Script scrpt = groovyShell.parse(filePath);
		int result=(int) scrpt.invokeMethod("updateSyncServerDate", new String[] { status, server });
		if(result == -1)
			throw new Exception("no server suitable for synchronization found");
		if(result!=0)
			throw new Exception("修改时间服务器失败.");
	}
	
	
	public static void updateSystemTimeStatus(int status) throws Exception {
		Properties p = new Properties();
	    FileInputStream fis = new FileInputStream(sysPropFile);
	    p.load(fis);
	    fis.close();
	   
	    p.setProperty("timestaus", String.valueOf(status));

	    FileOutputStream fos = new FileOutputStream(sysPropFilePath);
	    p.store(fos, null);
	    fos.flush();
	    fos.close();
	}
	
	public static void updateConfHostName(String  hostName) throws Exception {
		Properties p = new Properties();
	    FileInputStream fis = new FileInputStream(sysPropFile);
	    p.load(fis);
	    fis.close();
	   
	    p.setProperty("hostname", hostName);

	    FileOutputStream fos = new FileOutputStream(sysPropFilePath);
	    p.store(fos, null);
	    fos.flush();
	    fos.close();
	}
	
	public static void updateConfNetwork(String name, String ip, String netmask,
			String gateway, String dns) throws Exception {
		Properties p = new Properties();
	    FileInputStream fis = new FileInputStream(sysPropFile);
	    p.load(fis);
	    fis.close();
	   
	    p.setProperty("eth0", name);
	    p.setProperty("ip", ip);
	    p.setProperty("netmask", netmask);
	    p.setProperty("gateway", gateway);
	    p.setProperty("dns", dns);

	    FileOutputStream fos = new FileOutputStream(sysPropFilePath);
	    p.store(fos, null);
	    fos.flush();
	    fos.close();
	}
	
	public static int getSystemTimeStatus() throws Exception {
		int status = 0;
		Properties p = new Properties();
	    FileInputStream fis = new FileInputStream(sysPropFile);
	    p.load(fis);
	    fis.close();
	    String timestaus = p.getProperty("timestaus");
	    status = Integer.valueOf(StringUtils.isEmpty(timestaus)?"0":timestaus);
		return status;
	}
	
	public static String getSystemTimeSyncServer() throws Exception {
		Properties p = new Properties();
	    FileInputStream fis = new FileInputStream(sysPropFile);
	    p.load(fis);
	    fis.close();
	    String timesyncserver = p.getProperty("timesyncserver");
		return timesyncserver==null?"":timesyncserver;
	}
	
	public static void updateConfsyncServer(String status, String syncServer) throws Exception {
		Properties p = new Properties();
	    FileInputStream fis = new FileInputStream(sysPropFile);
	    p.load(fis);
	    fis.close();
	   
	    p.setProperty("timestaus", status);
	    p.setProperty("timesyncserver", syncServer);

	    FileOutputStream fos = new FileOutputStream(sysPropFilePath);
	    p.store(fos, null);
	    fos.flush();
	    fos.close();
	}
}
